home *** CD-ROM | disk | FTP | other *** search
- ;*---------------------------------------------------------------------------
- ; :Modul. savegame.s
- ; :Contents. routine for multiple save game support
- ; it creates an interface from which the user can choice between
- ; 9 different savegames, a description can be entered for each
- ; savegame, all savegames will be stored in one single file which
- ; grows dynamically
- ; the savegames must have always the same size
- ; :Author. Wepl
- ; :Version. $Id: savegame.s 1.2 1998/11/22 14:29:48 jah Exp $
- ; :History. 14.06.98 extracted from Interphase slave
- ; 15.06.98 returncode fixed
- ; problem with savegames larger than $7fff fixed
- ; :Requires. _keyexit byte variable containing rawkey code
- ; _exit function to quit
- ; :Copyright. Public Domain
- ; :Language. 68000 Assembler
- ; :Translator. Barfly V2.9
- ; :To Do.
- ;---------------------------------------------------------------------------*
- ; this is a example sequence to use the savegame routine
- ; during execution some custom registers will be destroyed, if the installed
- ; program does not refresh them itself, it must be done after calling the
- ; savegame routine
-
- IFEQ 1
-
- move.l #100,d0 ;savegame size
- lea $3e900,a0 ;address of savegame
- lea $65000,a1 ;free mem for screen
- bsr _sg_load
- ; move.w #$4100,(_custom+bplcon0)
- ; move.w #320/8*3,(_custom+bpl1mod)
- ; move.l #$00000eee,(_custom+color)
-
- ENDC
-
- ;--------------------------------
- ; IN: d0 = ULONG size (only on function save required)
- ; a0 = APTR address of load/save area
- ; a1 = APTR space for the screen ($2800 bytes)
- ; OUT: d0 = BOOL success
- ; d1/a0/a1 destroyed
-
- MAXNAMELEN = 40
- LINE = 320/8
- SCREEN = LINE*200
- SAVEDIRLEN = 4+10+(10*MAXNAMELEN)
- CHARHEIGHT = 5
- CHARWIDTH = 5
-
- INCLUDE macros/ntypes.i
-
- NSTRUCTURE SaveGame,0
- NLONG sg_screen
- NLONG sg_size
- NLONG sg_address
- NLONG sg_old68
- NLONG sg_old6c
- NWORD sg_oldintena
- NWORD sg_olddmacon
- NSTRUCT sg_save_names,10*MAXNAMELEN
- NSTRUCT sg_save_flags,10
- NSTRUCT sg_save_id,4
- NSTRUCT sg_tmpname,MAXNAMELEN
- NWORD sg_c_x
- NWORD sg_c_y
- NBYTE sg_key
- NBYTE sg_c_on
- NBYTE sg_success
- NALIGNLONG
- NLABEL sg_SIZEOF
-
- ;--------------------------------
- ; print save game directory
- ; IN: -
- ; OUT: -
-
- XBASE = 50
- YBASE = 40
- YSKIP = 15
-
- _sg_printdir moveq #XBASE,d0 ;x-pos
- moveq #YBASE-YSKIP,d1 ;first line
- moveq #'1',d2
- moveq #0,d3 ;amount saves
- .next add.w #YSKIP,d1 ;line skip
- bsr _pc
- movem.l d0/d2,-(a7)
- add.w #15,d0
- sub.w #'1',d2
- mulu.w #MAXNAMELEN,d2
- lea (sg_save_names,a5),a0
- add.w d2,a0
- bsr _ps
- movem.l (a7)+,d0/d2
- addq.b #1,d2
- cmp.b #'9',d2
- bls .next
- rts
-
- ;--------------------------------
- ; save a savegame
- ; IN: D0 = size of the savegame
- ; A0 = address to load savegame on
- ; A1 = address of free memory for screen ($2800 bytes)
- ; OUT: D0 = BOOL success
-
- _sg_save moveq #0,d1
- bra _sg_degrade
- _sg_save_in bsr _sg_loaddir
-
- .start moveq #7,d1
- lea _save,a0
- bsr _psc
- add.w #8,d1
- lea _saveselect,a0
- bsr _psc
- add.w #8,d1
- lea _esc,a0
- bsr _psc
-
- bsr _sg_printdir
-
- .keyloop bsr _sg_get_key
- cmp.b #$45,d0
- beq _sg_restore
-
- lea (_keytrans),a0
- move.b (a0,d0.w),d1
- cmp.b #'1',d1
- blo .keyloop
- cmp.b #'9',d1
- bhi .keyloop
-
- moveq #XBASE+9,d0
- sub.w #'1',d1
- move.w d1,d6 ;D6 = save no.
- mulu #YSKIP,d1
- add.w #YBASE-5,d1
- move.w d0,d2
- add.w #210,d2
- move.w d1,d3
- add.w #YSKIP-1,d3
- bsr _sg_rect
-
- move.w d6,d0
- mulu.w #MAXNAMELEN,d0
- lea (sg_save_names,a5),a3
- add.w d0,a3 ;A3 = save name
-
- move.l a3,a0
- lea (sg_tmpname,a5),a1
- .cpy move.b (a0)+,(a1)+
- bne .cpy
-
- .chkname moveq #-1,d5
- move.l a3,a0
- .cnt addq.w #1,d5 ;D5 = charpos in save name
- tst.b (a0)+
- bne .cnt
-
- move.w d5,d0
- mulu #CHARWIDTH,d0
- add.w #XBASE+15,d0
- move.w d0,(sg_c_x,a5)
- move.w d6,d1
- mulu #YSKIP,d1
- add.w #YBASE,d1
- move.w d1,(sg_c_y,a5)
- st (sg_c_on,a5)
-
- moveq #15,d1
- lea _saveinsert,a0
- bsr _psc
-
- .nextkey bsr _sg_get_key
- cmp.b #$43,d0 ;enter
- beq .return
- cmp.b #$44,d0 ;return
- beq .return
- cmp.b #$41,d0 ;backspace
- beq .bs
- cmp.b #$46,d0 ;delete
- beq .bs
- cmp.b #$45,d0 ;escape
- beq .esc
- cmp.w #MAXNAMELEN-1,d5
- beq .nextkey
- lea (_keytrans),a0
- move.b (a0,d0.w),d2
- beq .nextkey
- move.b d2,(a3,d5.w)
- addq.w #1,d5
- move.w (sg_c_x,a5),d0
- move.w (sg_c_y,a5),d1
- add.w #CHARWIDTH,(sg_c_x,a5)
- bsr _pc
- bra .nextkey
-
- .bs tst.w d5
- beq .nextkey
- bsr _sg_cursoroff
- subq.w #1,d5
- clr.b (a3,d5.w)
- bra .chkname
-
- .esc bsr _sg_cursoroff
- lea (sg_tmpname,a5),a0
- move.l a3,a1
- .cpy2 move.b (a0)+,(a1)+
- bne .cpy2
- bsr _sg_initscr
- bra .start
-
- .return tst.w d5 ;a name specified ?
- beq .esc
- bsr _sg_cursoroff
-
- moveq #15,d1
- lea _saveconfirm,a0
- bsr _psc
-
- .nextkey2 bsr _sg_get_key
- cmp.b #$45,d0 ;escape
- beq .esc
- cmp.b #$43,d0 ;enter
- beq .confirmed
- cmp.b #$44,d0 ;return
- bne .nextkey2
-
- .confirmed lea (sg_save_flags,a5),a0
- st (a0,d6.w)
-
- move.l #SAVEDIRLEN,d0 ;size
- moveq #0,d1 ;offset
- lea (_sg_name),a0 ;filename
- lea (sg_save_id,a5),a1 ;address
- move.w #resload_SaveFileOffset,a2
- bsr _sg_exec_resload
-
- move.l (sg_size,a5),d0 ;size
- move.l #SAVEDIRLEN,d1
- bra .loopin
- .loop add.l d0,d1 ;offset
- .loopin subq.w #1,d6
- bpl .loop
- lea (_sg_name),a0 ;filename
- move.l (sg_address,a5),a1 ;address
- move.w #resload_SaveFileOffset,a2
- bsr _sg_exec_resload
-
- st (sg_success,a5)
- bra _sg_restore
-
- ;--------------------------------
- ; disable text cursor
- ; IN: -
- ; OUT: -
-
- _sg_cursoroff sf (sg_c_on,a5)
- move.w (sg_c_x,a5),d0
- move.w (sg_c_y,a5),d1
- move.w #' ',d2
- bra _pc
-
- ;--------------------------------
- ; clear screen
- ; IN: -
- ; OUT: -
-
- _sg_clrscr movem.l d0/a0,-(a7)
-
- move.l (sg_screen,a5),a0
- move.w #(320*256/8)/4-1,d0
- .clr clr.l (a0)+
- dbf d0,.clr
-
- movem.l (a7)+,d0/a0
- rts
-
- ;--------------------------------
- ; init screen
- ; IN: -
- ; OUT: -
-
- _sg_initscr movem.l d0-d3/a0,-(a7)
-
- bsr _sg_clrscr
-
- ;draw border
- ; moveq #0,d0
- ; moveq #0,d1
- ; move.w #319,d2
- ; move.w #199,d3
- ; bsr _sg_rect
- ;print info
- move.w #180,d1
- lea _info1,a0
- bsr _psc
- add.w #8,d1
- lea _info2,a0
- bsr _psc
-
- movem.l (a7)+,d0-d3/a0
- rts
-
- ;--------------------------------
- ; load a savegame
- ; IN: A0 = address to load savegame on
- ; A1 = address of free memory for screen ($2800 bytes)
- ; OUT: D0 = BOOL success
-
- _sg_load moveq #-1,d1
- bra _sg_degrade
- _sg_load_in bsr _sg_loaddir
- beq .nosavegame
-
- .start moveq #7,d1
- lea _load,a0
- bsr _psc
- add.w #8,d1
- lea _loadselect,a0
- bsr _psc
- add.w #8,d1
- lea _esc,a0
- bsr _psc
-
- bsr _sg_printdir
-
- lea (sg_save_names,a5),a0
- moveq #0,d0
-
-
- .keyloop bsr _sg_get_key
- cmp.b #$45,d0
- beq _sg_restore
-
- lea (_keytrans),a0
- moveq #0,d1
- move.b (a0,d0.w),d1
- cmp.b #'1',d1
- blo .keyloop
- cmp.b #'9',d1
- bhi .keyloop
-
- lea (sg_save_flags,a5),a0
- tst.b (-'1',a0,d1.w)
- beq .keyloop
-
- moveq #XBASE+9,d0
- sub.w #'1',d1
- move.w d1,d6 ;D6 = save no.
- mulu #YSKIP,d1
- add.w #YBASE-5,d1
- move.w d0,d2
- add.w #210,d2
- move.w d1,d3
- add.w #YSKIP-1,d3
- bsr _sg_rect
-
- moveq #15,d1
- lea _loadconfirm,a0
- bsr _psc
-
- .nextkey2 bsr _sg_get_key
- cmp.b #$43,d0 ;enter
- beq .confirmed
- cmp.b #$44,d0 ;return
- beq .confirmed
- cmp.b #$45,d0 ;escape
- bne .nextkey2
- bsr _sg_initscr
- bra .start
-
- .confirmed move.l (sg_size,a5),d0 ;size
- move.l #SAVEDIRLEN,d1
- bra .loopin
- .loop add.l d0,d1 ;offset
- .loopin subq.w #1,d6
- bpl .loop
- lea (_sg_name),a0 ;filename
- move.l (sg_address,a5),a1 ;address
- move.w #resload_LoadFileOffset,a2
- bsr _sg_exec_resload
-
- st (sg_success,a5)
- bra _sg_restore
-
- .nosavegame moveq #60,d1
- lea _loadno1,a0
- bsr _psc
- add.w #8,d1
- lea _loadno2,a0
- bsr _psc
- bsr _sg_get_key
- bra _sg_restore
-
- ;--------------------------------
- ; loads save directory
- ; IN: -
- ; OUT: D0 = BOOL success
- ; flags on D0
-
- _sg_loaddir lea (_sg_name),a0
- move.w #resload_GetFileSize,a2
- bsr _sg_exec_resload
- tst.l d0
- beq .nocurrentfile
-
- move.l #SAVEDIRLEN,d0 ;size
- moveq #0,d1 ;offset
- lea (_sg_name),a0 ;filename
- lea (sg_save_id,a5),a1 ;address
- move.w #resload_LoadFileOffset,a2
- bsr _sg_exec_resload
- cmp.l #"Wepl",(sg_save_id,a5)
- bne .nocurrentfile
- moveq #-1,d0 ;successful loaded
- rts
-
- .nocurrentfile lea (sg_save_id,a5),a0
- move.w #SAVEDIRLEN/4-1,d0
- .clr0 clr.l (a0)+
- dbf d0,.clr0
- move.l #"Wepl",(sg_save_id,a5)
- moveq #0,d0 ;nothing current
- rts
-
- ;--------------------------------
- ; execute resload function
-
- _sg_exec_resload
- move.w #INTF_INTEN,(intena,a6)
- add.l (_resload),a2
- jsr (a2)
- move.w #INTF_SETCLR!INTF_INTEN,(intena,a6)
- clr.l ($144,a6)
- clr.l ($14c,a6)
- rts
-
- ;--------------------------------
-
- _sg_get_key clr.b (sg_key,a5)
- moveq #0,d0
- .waitdown move.b (sg_key,a5),d0
- ble .waitdown
- bchg #7,d0
- .waitup cmp.b (sg_key,a5),d0
- bne .waitup
- bclr #7,d0
- rts
-
- ;--------------------------------
-
- _sg_degrade movem.l d2-d7/a2-a6,-(a7)
- link a5,#sg_SIZEOF ;A5 = data
- move.l d0,(sg_size,a5)
- move.l a0,(sg_address,a5)
- move.l a1,(sg_screen,a5)
- sf (sg_c_on,a5)
- sf (sg_success,a5)
- bsr _sg_waitvb
- move.w (_custom+intenar),(sg_oldintena,a5)
- move.w #$7fff,(_custom+intena)
- lea (_custom),a6 ;A6 = _custom
- move.w (dmaconr,a6),(sg_olddmacon,a5)
- move.w #$7fff,(dmacon,a6)
- bsr _sg_initscr
- lea (_sg_int68),a0
- move.l $68,(sg_old68,a5)
- move.l a0,$68
- lea (_sg_int6c),a0
- move.l $6c,(sg_old6c,a5)
- move.l a0,$6c
- move.w #INTF_SETCLR|INTF_INTEN|INTF_VERTB|INTF_PORTS,(intena,a6)
- tst.b (ciaicr+_ciaa) ;clear all intreq
- move.w #INTF_VERTB|INTF_PORTS,(intreq,a6)
- bsr _sg_waitvb
- move.w #$1200,(bplcon0,a6)
- clr.w (bpl1mod,a6)
- move.l #$00000eee,(color,a6)
- move.w #DMAF_SETCLR|DMAF_MASTER|DMAF_RASTER,(dmacon,a6)
- tst.l d1
- beq _sg_save_in
- bra _sg_load_in
-
- ;--------------------------------
-
- _sg_restore bsr _sg_clrscr
- move.b (sg_success,a5),d0
- ext.w d0
- move.w d0,a0 ;a0 = success
- bsr _sg_waitvb
- move.w #$7fff,(intena,a6)
- move.w #$7fff,(dmacon,a6)
- move.l (sg_old68,a5),$68
- move.l (sg_old6c,a5),$6c
- move.w #$7fff,(intreq,a6)
- move.w (sg_oldintena,a5),d0
- bset #15,d0 ;d0 = intena
- move.w (sg_olddmacon,a5),d1
- bset #15,d1 ;d1 = dmacon
- unlk a5
- movem.l (a7)+,d2-d7/a2-a6
- move.w d0,(_custom+intena)
- bsr _sg_waitvb
- move.w d1,(_custom+dmacon)
- move.l a0,d0 ;success
- rts
-
- ;--------------------------------
-
- _sg_int68 movem.l d0-d1,-(a7)
- btst #CIAICRB_SP,(ciaicr+_ciaa) ;check int reason
- beq .int2_exit
- move.b (ciasdr+_ciaa),d0 ;read code
- clr.b (ciasdr+_ciaa) ;output LOW (handshake)
- or.b #CIACRAF_SPMODE,(ciacra+_ciaa) ;to output
- not.b d0
- ror.b #1,d0
- cmp.b (_keyexit),d0
- beq _exit
- move.b d0,(sg_key,a5)
- moveq #3-1,d1 ;wait because handshake min 75 µs
- .int2_w1 move.b (vhposr,a6),d0
- .int2_w2 cmp.b (vhposr,a6),d0 ;one line is 63.5 µs
- beq .int2_w2
- dbf d1,.int2_w1 ;(min=127µs max=190.5µs)
- and.b #~(CIACRAF_SPMODE),(ciacra+_ciaa) ;to input
- .int2_exit move.w #INTF_PORTS,(intreq,a6)
- movem.l (a7)+,d0-d1
- rte
-
- ;--------------------------------
-
- _sg_int6c move.l (sg_screen,a5),(bplpt,a6)
- tst.b (sg_c_on,a5)
- beq .1
- movem.l d0-d2,-(a7)
- move.w (sg_c_x,a5),d0
- move.w (sg_c_y,a5),d1
- move.w #' ',d2
- bchg #0,(sg_c_on,a5)
- beq .2
- move.w #'_',d2
- .2 bsr _pc
- movem.l (a7)+,d0-d2
- .1 move.w #INTF_VERTB,(intreq,a6)
- rte
-
- ;--------------------------------
-
- _sg_waitvb waitvb
- rts
-
- ;--------------------------------
- ; draw rectangle
- ; IN: d0 = word x start
- ; d1 = word y start
- ; d2 = word x stop
- ; d3 = word y stop
- ; OUT: -
-
- _sg_rect bsr _sg_xline
- exg d1,d3
- bsr _sg_xline
- exg d1,d2
- exg d1,d3
- bsr _sg_yline
- exg d0,d3
- bra _sg_yline
-
- ;--------------------------------
- ; line in x axis
- ; IN: d0 = word x start
- ; d1 = word y start
- ; d2 = word x stop
- ; OUT: -
-
- _sg_xline movem.l d0/d2,-(a7)
- cmp.w d0,d2
- beq .end
- bhi .in
- exg d0,d2
- bra .in
- .next addq.w #1,d0
- .in bsr _sg_pset
- cmp.w d0,d2
- bne .next
- .end movem.l (a7)+,d0/d2
- rts
-
- ;--------------------------------
- ; line in y axis
- ; IN: d0 = word x start
- ; d1 = word y start
- ; d2 = word y stop
- ; OUT: -
-
- _sg_yline movem.l d1/d2,-(a7)
- cmp.w d1,d2
- beq .end
- bhi .in
- exg d1,d2
- bra .in
- .next addq.w #1,d1
- .in bsr _sg_pset
- cmp.w d1,d2
- bne .next
- .end movem.l (a7)+,d1/d2
- rts
-
- ;--------------------------------
- ; set a pixel
- ; IN: d0 = word x start
- ; d1 = word y start
- ; OUT: -
-
- _sg_pset move.l d1,-(a7)
- bsr _getscrptr
- move.w d0,d1
- lsr.w #3,d1
- add.w d1,a0
- moveq #7,d1
- and.w d0,d1
- neg.w d1
- addq.w #7,d1
- bset d1,(a0)
- move.l (a7)+,d1
- rts
-
- ;--------------------------------
- ; IN: d1 = word y start
- ; OUT: a0 = ptr
-
- _getscrptr move.l (sg_screen,a5),a0
- mulu #LINE,d1
- add.l d1,a0
- rts
-
- ;--------------------------------
- ; print string centered
- ; IN: d1 = word y
- ; a0 = cptr string
- ; OUT: d0 = word new x
-
- _psc move.l a0,-(a7)
- moveq #0,d0
- .count tst.b (a0)+
- beq .1
- subq.w #CHARWIDTH,d0
- bra .count
- .1 asr.w #1,d0
- add.w #LINE*4,d0
- move.l (a7)+,a0
- bra _ps
-
- ;--------------------------------
- ; print string
- ; IN: d0 = word x
- ; d1 = word y
- ; a0 = cptr string
- ; OUT: d0 = word new x
-
- _ps movem.l d2,-(a7)
- moveq #0,d2
- bra .in
- .next bsr _pc
- add.w #CHARWIDTH,d0
- .in move.b (a0)+,d2
- bne .next
- movem.l (a7)+,d2
- rts
-
- ;--------------------------------
- ; print char
- ; IN: d0 = word x
- ; d1 = word y
- ; d2 = char
-
- _pc movem.l d0-d5/a0-a1,-(a7)
- bsr _getscrptr
- sub.w #32,d2
- mulu #CHARWIDTH,d2
- lea (_font),a1
- moveq #CHARHEIGHT-1,d3
- .cp
- IFD _68020_
- bfextu (a1){d2:CHARWIDTH},d1
- bfins d1,(a0){d0:CHARWIDTH}
- ELSE
- move.l d2,d1
- lsr.l #4,d1 ;words
- add.l d1,d1 ;bytes down rounded to word
- move.l (a1,d1.l),d1
- move.l d2,d4
- and.w #%1111,d4
- lsl.l d4,d1
- and.l #$ffffffff<<(32-CHARWIDTH),d1
- move.l #$ffffffff>>CHARWIDTH,d5
- move.l d0,d4
- and.w #%1111,d4
- lsr.l d4,d1
- ror.l d4,d5
- move.l d0,d4
- lsr.l #4,d4 ;words
- add.l d4,d4 ;bytes down rounded to word
- and.l d5,(a0,d4.l)
- or.l d1,(a0,d4.l)
- ENDC
- add.l #(_font_-_font)*8/CHARHEIGHT,d2
- add.l #LINE*8,d0
- dbf d3,.cp
- movem.l (a7)+,d0-d5/a0-a1
- rts
-
- _font INCBIN pics/pic_font_5x6_br.bin
- _font_
-
- ;--------------------------------
-
- _sg_name dc.b "savegame",0
- _info1 dc.b "special multiple savegame support",0
- _info2 dc.b "written by wepl in spring 1998",0
- _esc dc.b "press esc to cancel",0
- _save dc.b ">>> save a game <<<",0
- _saveselect dc.b "select a save position using the keyboard '1' - '9'",0
- _saveinsert dc.b " type in a description for this save position ",0
- _saveconfirm dc.b " confirm this save operation (return) ",0
- _load dc.b ">>> load a game <<<",0
- _loadselect dc.b "select a load position using the keyboard '1' - '9'",0
- _loadconfirm dc.b " confirm this load operation (return) ",0
- _loadno1 dc.b "sorry there is currently no valid savegame to load",0
- _loadno2 dc.b "press any key to continue",0
-
- _keytrans dc.b 0,"1234567890",0,0,"0",0,0
- dc.b "qwertyuiop",0,0,0,"123"
- dc.b "asdfghjkl",0,0,0,0,"456"
- dc.b 0,"zxcvbnm,.-",0,0,"789"
- dc.b " ",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- dc.b "123456789",0,0,0,0,0,0,0
- ds.b 16
- ds.b 16
-
-